home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 334_01 / doc2ms.c < prev    next >
Text File  |  1991-02-04  |  5KB  |  233 lines

  1. /*
  2.  * doc2ms.c  -- program to convert Gnuplot .DOC format to *roff -ms document
  3.  * From hlp2ms by Thomas Williams 
  4.  *
  5.  * Modified by Russell Lang, 2nd October 1989
  6.  * to make vms help level 1 and 2 create the same ms section level.
  7.  *
  8.  * Modified to become doc2ms by David Kotz dfk@cs.duke.edu 12/89
  9.  * Added table and backquote support.
  10.  *
  11.  * usage:  doc2ms < file.doc > file.ms
  12.  *
  13.  *   where file.doc is a VMS .DOC file, and file.ms will be a [nt]roff
  14.  *     document suitable for printing with nroff -ms or troff -ms
  15.  *
  16.  * typical usage for GNUPLOT:
  17.  *
  18.  *   doc2ms < gnuplot.doc | troff -ms
  19.  */
  20.  
  21. static char rcsid[] = "$Id: doc2ms.c,v 1.3 90/12/19 10:01:11 dfk Patch2 $";
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25.  
  26. #define MAX_NAME_LEN    256
  27. #define MAX_LINE_LEN    256
  28. #define LINE_SKIP        3
  29.  
  30. #define TRUE 1
  31. #define FALSE 0
  32.  
  33. typedef int boolean;
  34.  
  35. static boolean intable = FALSE;
  36.  
  37. main()
  38. {
  39.     init(stdout);
  40.     convert(stdin,stdout);
  41.     finish(stdout);
  42.     exit(0);
  43. }
  44.  
  45.  
  46. init(b)
  47. FILE *b;
  48. {
  49.     /* in nroff, increase line length by 8 and don't adjust lines */
  50.     (void) fputs(".if n \\{.nr LL +8m\n.na \\}\n",b);
  51.     (void) fputs(".nr PO +0.3i\n",b);
  52.     (void) fputs(".so titlepage.ms\n",b);
  53.     (void) fputs(".pn 1\n",b);
  54.     (void) fputs(".ds CH GNUPLOT\n",b);
  55.     (void) fputs(".ds RH Page %\n",b);
  56.     (void) fputs(".bp\n",b);
  57.     (void) fputs(".nr PS 12\n",b);
  58.     (void) fputs(".nr VS 13\n",b);
  59.     (void) fputs(".ta 1.5i 3.0i 4.5i 6.0i 7.5i\n",b);
  60.     (void) fputs("\\&\n.sp 3\n.PP\n",b);
  61.     /* following line commented out by rjl
  62.       (void) fputs(".so intro\n",b);
  63.       */
  64. }
  65.  
  66.  
  67. convert(a,b)
  68.     FILE *a,*b;
  69. {
  70.     static char line[MAX_LINE_LEN];
  71.  
  72.     while (fgets(line,MAX_LINE_LEN,a)) {
  73.        process_line(line, b);
  74.     }
  75. }
  76.  
  77. process_line(line, b)
  78.     char *line;
  79.     FILE *b;
  80. {
  81.     switch(line[0]) {        /* control character */
  82.        case '?': {            /* interactive help entry */
  83.           break;            /* ignore */
  84.        }
  85.        case '@': {            /* start/end table */
  86.           if (intable) {
  87.              (void) fputs(".TE\n", b);
  88.              (void) fputs(".EQ\ndelim off\n.EN\n\n",b);
  89.              intable = FALSE;
  90.           } else {
  91.              (void) fputs("\n.EQ\ndelim $$\n.EN\n",b);
  92.              (void) fputs(".TS\ncenter box tab (@) ;\n", b);
  93.              (void) fputs("c c l .\n", b);
  94.              intable = TRUE;
  95.           }
  96.           /* ignore rest of line */
  97.           break;
  98.        }
  99.        case '#': {            /* latex table entry */
  100.           break;            /* ignore */
  101.        }
  102.        case '%': {            /* troff table entry */
  103.           if (intable)
  104.             (void) fputs(line+1, b); /* copy directly */
  105.           else
  106.             fprintf(stderr, "error: % line found outside of table\n");
  107.           break;
  108.        }
  109.        case '\n':            /* empty text line */
  110.        case ' ': {            /* normal text line */
  111.           if (intable)
  112.             break;        /* ignore while in table */
  113.           switch(line[1]) {
  114.              case ' ': {
  115.                 /* verbatim mode */
  116.                 fputs(".br\n",b); 
  117.                 fputs(line+1,b); 
  118.                 fputs(".br\n",b);
  119.                 break;
  120.              }
  121.              case '\'': {
  122.                 fputs("\\&",b);
  123.                 putms(line+1,b); 
  124.                 break;
  125.              }
  126.              default: {
  127.                 if (line[0] == '\n')
  128.                   putms(line,b); /* handle totally blank line */
  129.                 else
  130.                   putms(line+1,b);
  131.                 break;
  132.              }
  133.              break;
  134.           }
  135.           break;
  136.        }
  137.        default: {
  138.           if (isdigit(line[0])) { /* start of section */
  139.              if (!intable)    /* ignore while in table */
  140.                section(line, b);
  141.           } else
  142.             fprintf(stderr, "unknown control code '%c' in column 1\n", 
  143.                   line[0]);
  144.           break;
  145.        }
  146.     }
  147. }
  148.  
  149.  
  150. /* process a line with a digit control char */
  151. /* starts a new [sub]section */
  152.  
  153. section(line, b)
  154.     char *line;
  155.     FILE *b;
  156. {
  157.     static char string[MAX_LINE_LEN];
  158.     int sh_i;
  159.     static int old = 1;
  160.  
  161.     (void) sscanf(line,"%d %[^\n]s",&sh_i,string);
  162.     
  163.     (void) fprintf(b,".sp %d\n",(sh_i == 1) ? LINE_SKIP : LINE_SKIP-1);
  164.     
  165.     if (sh_i > old) {
  166.        do
  167.         if (old!=1)    /* this line added by rjl */
  168.           (void) fputs(".RS\n.IP\n",b);
  169.        while (++old < sh_i);
  170.     }
  171.     else if (sh_i < old) {
  172.        do
  173.                if (sh_i!=1) /* this line added by rjl */
  174.                 (void) fputs(".RE\n.br\n",b);
  175.        while (--old > sh_i);
  176.     }
  177.     
  178.     /* added by dfk to capitalize section headers */
  179.     if (islower(string[0]))
  180.      string[0] = toupper(string[0]);
  181.     
  182.     /* next 3 lines added by rjl */
  183.     if (sh_i!=1) 
  184.      (void) fprintf(b,".NH %d\n%s\n.sp 1\n.LP\n",sh_i-1,string);
  185.     else 
  186.      (void) fprintf(b,".NH %d\n%s\n.sp 1\n.LP\n",sh_i,string);
  187.     old = sh_i;
  188.     
  189.     (void) fputs(".XS\n",b);
  190.     (void) fputs(string,b);
  191.     (void) fputs("\n.XE\n",b);
  192. }
  193.  
  194. putms(s, file)
  195.     char *s;
  196.     FILE *file;
  197. {
  198.     static boolean inquote = FALSE;
  199.  
  200.     while (*s != '\0') {
  201.        switch (*s) {
  202.           case '`': {        /* backquote -> boldface */
  203.              if (inquote) {
  204.                 fputs("\\fR", file);
  205.                 inquote = FALSE;
  206.              } else {
  207.                 fputs("\\fB", file);
  208.                 inquote = TRUE;
  209.              }
  210.              break;
  211.           }
  212.           case '\\': {        /* backslash */
  213.              fputs("\\\\", file);
  214.              break;
  215.           }
  216.           default: {
  217.              fputc(*s, file);
  218.              break;
  219.           }
  220.        }
  221.        s++;
  222.     }
  223. }
  224.  
  225. finish(b)        /* spit out table of contents */
  226. FILE *b;
  227. {
  228.     (void) fputs(".pn 1\n",b);
  229.     (void) fputs(".ds RH %\n",b);
  230.     (void) fputs(".af % i\n",b);
  231.     (void) fputs(".bp\n.PX\n",b);
  232. }
  233.